import 'dart:convert';
import 'dart:typed_data';

import 'package:wk_robot2/app/blt/RobotCommands.dart';
import 'package:wk_robot2/app/blt/RobotCommandsHelper.dart';
import 'package:wk_robot2/app/blt/protobuf/CodeMao_Message.pb.dart';
import 'package:wk_robot2/app/event/DataCallBack.dart';
import 'package:wk_robot2/app/utils/CommonUtil.dart';

import '../../const/AppConst.dart';
import '../../logger/Logger.dart';
import '../protobuf/BluetoothHandShake.pb.dart';


// 假设PacketMessage类已经定义
class PacketMessage {
  int? cmdId;
  int? serialNo;
  Uint8List? dataContent;

  @override
  String toString() {
    return 'PacketMessage{cmdId: $cmdId, serialNo: $serialNo, dataContent: ${dataContent!.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join()}}';
  }
}

// 假设这是将两个字节转换为一个短整型值的函数（Dart中没有直接的short类型，但我们可以使用int）
int bytesToShort(Uint8List bytes) {
  return (bytes[0] << 8) | bytes[1];
}

class MiniBleProto {

  static const int LEN_INDEX = 3;
  List<int> pack_header = [0xfb,0xbf];
  static int PACK_END = 0xed;
  static int VERSION_INDEX = 2;


  static final MiniBleProto INSTANCE = MiniBleProto();


  PacketMessage parsePacketMsg(Uint8List data) {
      int cmdIdIndex = data.length - 3 -1;
      int serialNoIndex = data.length - 1 -1;

      // 检查索引是否有效
     /* if (cmdIdIndex < 0 || serialNoIndex < 0 || cmdIdIndex + 1 >= data.length || serialNoIndex + 1 >= data.length) {
        throw ArgumentError('Invalid data length for parsing');
      }*/

      Uint8List cmdIdBytes = data.sublist(cmdIdIndex, cmdIdIndex + 2);
      Uint8List serialNoBytes = data.sublist(serialNoIndex, serialNoIndex + 2);

      PacketMessage packetMsg = PacketMessage();
      packetMsg.cmdId = bytesToShort(cmdIdBytes);
      packetMsg.serialNo = bytesToShort(serialNoBytes);
      packetMsg.dataContent = data.sublist(0, cmdIdIndex);

      print(packetMsg);
      return packetMsg;
  }


  Pair<int, List<MiniMessage>> unpack(Uint8List data) {
    int idx = 0;
    List<MiniMessage> res = [];

    while (idx + LEN_INDEX < data.length) {
      // 检查头部
      if (data[idx] != pack_header[0] || data[idx + 1] != pack_header[1]) {
        return Pair(-1, res);
      }

      // 获取长度
      Uint8List lenBytes = data.sublist(idx + LEN_INDEX, idx + LEN_INDEX + 2);
      int len = CommonUtil.bytesToInt(lenBytes);
      print("data len = $len");

      // 检查数据长度是否足够
      if (data.length - idx < len + 1) {
        break;
      } else {
        // 检查尾部
        if (data[idx + len] != PACK_END) {
          return Pair(-1, res);
        }

        // 解析消息
        MiniMessage msg = MiniMessage();
        msg.versionCode = data[idx + VERSION_INDEX];
        msg.dataContent = data.sublist(idx + LEN_INDEX + 2, idx + len - 1);
        res.add(msg);

        // 更新索引
        idx += 1 + len;
      }
    }

    return Pair(idx, res);
  }




}


class MiniMessage {
  // MiniMessage的属性和方法
  int? sendSerial;
  int? responseSerial;
  int? commandId;
  Uint8List? dataContent;
  int? versionCode = 0;

  // 假设有这些方法用于设置和获取属性
  void setSendSerial(int sendSerial) {
    this.sendSerial = sendSerial;
  }

  void setResponseSerial(int responseSerial) {
    this.responseSerial = responseSerial;
  }

  void setCommandId(int commandId) {
    this.commandId = commandId;
  }

  void setDataContent(Uint8List dataContent) {
    this.dataContent = dataContent;
  }

  int? getSendSerial() {
    return sendSerial;
  }

  int? getResponseSerial() {
    return responseSerial;
  }

  int? getCommandId() {
    return commandId;
  }

  Uint8List? getDataContent() {
    return dataContent;
  }

}

class PacketData {

  int _nCapacity = 0;
  int _nPosition = 0;
  Uint8List _buffer = Uint8List(0);
  int cmdId = 0;
  int serialNo = 0;
  bool isFirst = true;
  final String TAG = 'PacketData';

  static final PacketData _instance = PacketData._();
  PacketData._();


  factory PacketData.get() => _instance;

  void putBytes(PacketMessage packetMessage) {
    if (isFirst) {
      // 第一次初始化
      this.cmdId = packetMessage.cmdId!;
      this.serialNo = packetMessage.serialNo!;
      isFirst = false;
    } else {
      if (this.cmdId != packetMessage.cmdId) {
        // 中间有丢包，则把上次内容全部清空,重新开始走
        clear();
        putBytes(packetMessage); // 递归调用，注意这里的递归可能会导致栈溢出如果丢包频繁
        return;
      } else {
        if (this.serialNo == packetMessage.serialNo) {
          // 来了一个序列号重复的包，则跳过
          return;
        } else {
          this.serialNo = packetMessage.serialNo!;
        }
      }
    }

    // 分配空间并添加数据内容（这里需要改进以适应动态大小的缓冲区）
    // 注意：Dart 的 Uint8List 不支持直接像 ByteBuffer 那样 put 数据，我们需要创建一个新的列表
    Uint8List newData = Uint8List.fromList(packetMessage.dataContent!);
    Uint8List newBuffer = Uint8List(_buffer.length + newData.length);
    newBuffer.setAll(0, _buffer);
    newBuffer.setAll(_buffer.length, newData);
    _buffer = newBuffer;
    _nPosition = _buffer.length; // 或者保持一个单独的计数器来跟踪 nPosition
  }

  Uint8List getBuffer() {
    return _buffer;
  }


  void clear() {
    _buffer = Uint8List(0);
    _nPosition = 0;
    isFirst = true;
  }
}

class Pair<T1, T2> {
  final T1 first;
  final T2 second;

  Pair(this.first, this.second);
}


class ProtoBufferDispose {
  static Message? parseMessage(Uint8List dataContent) {
    return Message.fromBuffer(dataContent); // 假设直接调用CodeMaoMessage的静态方法
  }
}


// 解析主函数.
void handleProtoBuffMsg(Uint8List msgBytes, String peer,DataCallBack dataCallBack) {
 if (msgBytes.isEmpty) return;
  logger.info("flutter handleProtoBuffMsg content = ${CommonUtil.uint8ListToHex(msgBytes)}");

  PacketMessage? packetMessage = MiniBleProto.INSTANCE.parsePacketMsg(msgBytes);
  if (packetMessage == null) return;

  Pair<int, List<MiniMessage>>? unpackData = MiniBleProto.INSTANCE.unpack(packetMessage!.dataContent!);
  if (unpackData?.first == -1 || unpackData!.second.isEmpty) {
    // 如果不是一条命令则是数据包
    PacketData.get().putBytes(packetMessage!);
    Uint8List content = PacketData.get().getBuffer();
    Pair<int, List<MiniMessage>>? data = MiniBleProto.INSTANCE.unpack(content);
    if (data?.first != -1 && data!.second.isNotEmpty) {
      print('接受消息组包完成1.');
      parseMessage(data!.second, peer,dataCallBack);

    }
  } else {
    print('接受消息组包完成2.');
    // 组包完成
    parseMessage(unpackData!.second, peer,dataCallBack);
  }
}

// 转换后的parseMessage函数
void parseMessage(List<MiniMessage> dataPairs, String peer,DataCallBack dataCallBack) {
  logger.info("receive dataPairsSize = ${dataPairs.length}");

  for (var msgRequest in dataPairs) {
    if (msgRequest == null) {
      return;
    }

    var message = ProtoBufferDispose.parseMessage(msgRequest.dataContent!);
    if (message == null) {
      logger.info("cannot parse data content");
    } else {
      var miniMessage = MiniMessage();
      miniMessage.setResponseSerial(message.header.responseSerial); // 假设header有responseSerial属性
      miniMessage.setDataContent(CommonUtil.listToInt8List(message.bodyData)); // 假设bodyData有toByteArray方法
      miniMessage.setSendSerial(message.header.sendSerial); // 假设header有sendSerial属性
      miniMessage.setCommandId(message.header.commandId); // 假设header有commandId属性，并且需要转换为Dart的short（在Dart中通常是int）

      logger.info("handleProtoBuffMsg--cmdId = ${miniMessage.commandId}, requestId = ${miniMessage.sendSerial}, responseId = ${miniMessage.responseSerial}");
      DataCallBack? dataCallBack =
                HardwareCommands.dataCallBackMap[HardwareCommands.currentGlobalSendSequence];
      if (dataCallBack != null) {
       // HardwareCommands.dataCallBackMap.remove(HardwareCommands.currentGlobalSendSequence);
        dataCallBack.deviceCallBack!({
          AppConst.BTL_DATA_KEY: miniMessage.getDataContent()
        });


      }

     /*if (miniMessage.responseSerial! > 0) {
        if (dataCallBack != null) {
          dataCallBack.deviceCallBack!({
            AppConst.BTL_DATA_KEY: miniMessage.getDataContent()
          });
        }
     } else {
        if (dataCallBack != null) {
          dataCallBack.deviceCallBack!({
            AppConst.BTL_DATA_KEY: miniMessage.getDataContent()
          });
        }

     }*/



    }
  }

  PacketData._instance.clear(); // 清除数据
}

